var assign = Object.assign

class RouterBuilder {
  constructor (config, options) {
    var defaultOptions = {
      url: '',
      exclude: '',
      include: '',
      namespace: {},
      prefix: '',
      isServer: false
    }
    var self = this
    self.opts = assign(defaultOptions, options)
    self.version = '0.01.1'
    self.Routes = {}
    self.config = config
    if (config) {
      self.buildRoute(config)
    }
  }
  buildRoute (config) {
    var self = this
    var opts = self.opts
    var isServer = opts.isServer
    var Routes = self.Routes
    config = config || self.config

    function replaceNamespace (route, namespace, isServer) {
      var routeName = ''
      return [route.split('/').map(function (section) {
        if (section.charAt(0) !== ':') {
          routeName += section + '_'
          if (namespace[section]) {
            return namespace[section]
          }
          return section
        }
        return isServer ? section : ':'
      }), routeName]
    }

    config.forEach(function (route) {
      var routeName = ''
      var opts = {}
      if (typeof route !== 'string') {
        opts = route[1] || {}
        route = route[0]
      }
      if (opts.namespace) {
        opts.namespace = assign({}, self.opts.namespace, opts.namespace)
      }
      opts = assign({}, self.opts, opts)
      route = replaceNamespace(route, opts.namespace, opts.isServer)
      routeName = route[1]
      route = route[0]
      if (isServer) {
        var result = '/' + route.join('/')
        Routes[routeName + 'path'] = function () {
          return result
        }
        return
      }
      Routes[routeName + 'path'] = function () {
        var args = [].slice.call(arguments)
        var opt = args.slice(-1)[0]
        opt = typeof opt === 'string' ? undefined : opt
        var result = '/'
        var last
        result += route.map(function (section) {
          if (section !== ':') {
            last = section
            return section
          }
          if (args.length > 0) {
            return args.shift()
          }
          throw new Error(routeName + 'path(): ' + 'Routes params empty after[' + last + ']')
        }).join('/')
        if (opt) {
          if (opt.format) {
            result += '.' + opt.format
          }
          if (opt.anchor) {
            result += '#' + opt.anchor
          }
        }
        return result
      }
      Routes[routeName + 'url'] = function () {
        return opts.url + this[routeName + 'path'].apply(this, arguments)
      }
    })
    return this
  }
  value () {
    return this.Routes
  }
}

module.exports = RouterBuilder
